package com.toshi.netlib.base;

import com.toshi.netlib.environment.EnvironmentActivity;
import com.toshi.netlib.environment.IEnvironment;
import com.toshi.netlib.errorhandler.HttpErrorHandler;
import com.toshi.netlib.interceptors.CommonRequestInterceptor;
import com.toshi.netlib.interceptors.CommonResponseInterceptor;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import java.util.HashMap;

public abstract class NetworkApi implements IEnvironment {

    private static INetworkRequiredInfo networkRequiredInfo;//通过初始化获取appInfo的 依赖对象
    private static HashMap<String, Retrofit> retrofitHashMap = new HashMap<>();//用于存储不同Net接口地址的retrofit对象的map  用于多地址定义
    private String mBaseUrl;//子对象对应的baseUrl
    private OkHttpClient mOkHttpClient;
    private static boolean mIsFormal = true;

    public NetworkApi() {
//        if (!mIsFormal) {
//            mBaseUrl = getTest();
//        }
//        mBaseUrl = getFormal();
        mBaseUrl = mIsFormal ? getFormal() : getTest();
    }

    public static void init(INetworkRequiredInfo networkRequiredInfo) {
        NetworkApi.networkRequiredInfo = networkRequiredInfo;
        mIsFormal = EnvironmentActivity.isOfficialEnvironment(networkRequiredInfo.getApplicationContext());
    }

    protected Retrofit getRetrofit(Class service) {
        if (retrofitHashMap.get(mBaseUrl + service.getName()) != null) {
            return retrofitHashMap.get(mBaseUrl + service.getName());
        }
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl(mBaseUrl);
        builder.client(getOkHttpClient());
        builder.addConverterFactory(GsonConverterFactory.create());
        builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
        Retrofit retrofit = builder.build();
        retrofitHashMap.put(mBaseUrl + service.getName(), retrofit);
        return retrofit;
    }

    private OkHttpClient getOkHttpClient() {
        if (mOkHttpClient == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            if (getInterceptor() != null) {
                builder.addInterceptor(getInterceptor());
            }
            builder.addInterceptor(new CommonRequestInterceptor(networkRequiredInfo));
            builder.addInterceptor(new CommonResponseInterceptor());
            if (networkRequiredInfo != null && networkRequiredInfo.isDebug()) {
                //当时debug模式的时候  添加log拦截器  打印出请求过程和数据
                HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
                loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                builder.addInterceptor(loggingInterceptor);
            }
            mOkHttpClient = builder.build();
        }
        return mOkHttpClient;
    }

    public <T> ObservableTransformer<T, T> applySchedulers(final Observer<T> observer) {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                Observable<T> observable = (Observable<T>) upstream
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .map(getAppErrorHandler())
                        .onErrorResumeNext(new HttpErrorHandler<T>());
                observable.subscribe(observer);
                return observable;
            }
        };
    }

    protected abstract Interceptor getInterceptor();

    protected abstract <T> Function<T, T> getAppErrorHandler();

}
